package co.yixiang.hw.service.impl;

import cn.hutool.core.date.DateUtil;
import co.yixiang.hw.domain.YxStoreCoupon;
import co.yixiang.hw.domain.YxStoreCouponUser;
import co.yixiang.hw.domain.YxStoreOrderCartInfo;
import co.yixiang.hw.repository.YxStoreCouponRepository;
import co.yixiang.hw.repository.YxStoreOrderCartInfoRepository;
import co.yixiang.hw.service.YxStoreCouponIssueService;
import co.yixiang.hw.service.YxStoreCouponService;
import co.yixiang.hw.service.YxStoreOrderCartInfoService;
import co.yixiang.hw.service.dto.YxStoreCouponDto;
import co.yixiang.hw.service.dto.YxStoreCouponIssueDto;
import co.yixiang.hw.service.mapper.YxStoreCouponIssueMapper;
import co.yixiang.utils.*;
import co.yixiang.hw.repository.YxStoreCouponUserRepository;
import co.yixiang.hw.service.YxStoreCouponUserService;
import co.yixiang.hw.service.dto.YxStoreCouponUserDto;
import co.yixiang.hw.service.dto.YxStoreCouponUserQueryCriteria;
import co.yixiang.hw.service.mapper.YxStoreCouponUserMapper;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import javax.annotation.Resource;


/**
* @author Walert
* @date 2020-03-10
*/
@Service
//@CacheConfig(cacheNames = "yxStoreCouponUser")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class YxStoreCouponUserServiceImpl implements YxStoreCouponUserService {

    @Resource
    private YxStoreCouponUserRepository yxStoreCouponUserRepository;
    @Resource
    private YxStoreCouponUserMapper yxStoreCouponUserMapper;
    @Resource
    private YxStoreCouponIssueMapper yxStoreCouponIssueMapper;
    @Autowired
    private YxStoreCouponService couponService;
    @Autowired
    private YxStoreCouponIssueService couponIssueService;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private YxStoreOrderCartInfoRepository orderCartInfoRepository;


    @Override
    //@Cacheable
    public Map<String,Object> queryAll(YxStoreCouponUserQueryCriteria criteria, Pageable pageable){
        Page<YxStoreCouponUser> page = yxStoreCouponUserRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(yxStoreCouponUserMapper::toDto));
    }

    @Override
    //@Cacheable
    public List<YxStoreCouponUserDto> queryAll(YxStoreCouponUserQueryCriteria criteria){
        return yxStoreCouponUserMapper.toDto(yxStoreCouponUserRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    //@Cacheable(key = "#p0")
    public YxStoreCouponUserDto findById(Integer id) {
        YxStoreCouponUser yxStoreCouponUser = yxStoreCouponUserRepository.findById(id).orElseGet(YxStoreCouponUser::new);
        ValidationUtil.isNull(yxStoreCouponUser.getId(),"YxStoreCouponUser","id",id);
        return yxStoreCouponUserMapper.toDto(yxStoreCouponUser);
    }

    @Override
    //@CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public YxStoreCouponUserDto create(YxStoreCouponUser resources) {
        return yxStoreCouponUserMapper.toDto(yxStoreCouponUserRepository.save(resources));
    }

    @Override
    //@CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void update(YxStoreCouponUser resources) {
        YxStoreCouponUser yxStoreCouponUser = yxStoreCouponUserRepository.findById(resources.getId()).orElseGet(YxStoreCouponUser::new);
        ValidationUtil.isNull( yxStoreCouponUser.getId(),"YxStoreCouponUser","id",resources.getId());
        yxStoreCouponUser.copy(resources);
        yxStoreCouponUserRepository.save(yxStoreCouponUser);
    }

    @Override
    //@CacheEvict(allEntries = true)
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            yxStoreCouponUserRepository.deleteById(id);
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveCouponUser(JSONObject params){
        Integer uid = params.getInteger("uid");
        Integer cid = params.getInteger("cid");
        Integer couponIssueId = params.getInteger("issueCouponId");

        YxStoreCouponDto coupon = couponService.findById(cid);
        YxStoreCouponIssueDto couponIssue = couponIssueService.findById(couponIssueId);

        Integer couponTime = coupon.getCouponTime();
        Long curTime = System.currentTimeMillis()/1000L;
        int endTime = curTime.intValue() + (couponTime * 24 * 60 * 60);
        YxStoreCouponUser couponUser = new YxStoreCouponUser();
        couponUser.setEndTime(endTime);
        couponUser.setAddTime(curTime.intValue());
        couponUser.setCid(cid);
        couponUser.setUid(uid);
        couponUser.setCouponPrice(coupon.getCouponPrice());
        couponUser.setUseMinPrice(coupon.getUseMinPrice());
        couponUser.setCouponTitle(coupon.getTitle());
        couponUser.setType("get");
        couponUser.setStatus(0);
        couponUser.setIsFail(0);
        couponUser.setUseTime(0);
        couponUser.setIssueCouponId(couponIssueId);
        this.create(couponUser);
        Double count = redisUtils.hdecr("coupon::issue-" + couponIssue.getId(),"issue" , 1);


        couponIssue.setRemainCount(count.intValue());
        couponIssueService.update(yxStoreCouponIssueMapper.toEntity(couponIssue));

    }

    @Override
    public List<YxStoreCouponUser> getUserCanUseCouponList(Integer uid, Integer goodsId){
        Long time =  System.currentTimeMillis() /1000L;
        return yxStoreCouponUserRepository.getUserCouponList(uid, goodsId, time.intValue());
    }

    @Override
    public List<Map> getUserCanUseCouponListV2(Integer uid){
        Long time =  System.currentTimeMillis() /1000L;
        return yxStoreCouponUserRepository.getUserCouponListV2(uid, time.intValue());
    }

    @Override
    public void useCoupon(Integer userCouponId,String orderNum){
        YxStoreCouponUserDto userCoupon = this.findById(userCouponId);
        Long useTime = System.currentTimeMillis()/1000L;
        userCoupon.setUseTime(useTime.intValue());
        userCoupon.setStatus(1);
        userCoupon.setUseOrderNum(orderNum);
        this.update(yxStoreCouponUserMapper.toEntity(userCoupon));
    }


    @Override
    public void useCouponByOrderId(Integer orderId, String orderNum){
        List<YxStoreOrderCartInfo> cartInfoList = orderCartInfoRepository.findByOid(orderId);
        if(cartInfoList != null && cartInfoList.size() > 0){
            for (int i = 0; i < cartInfoList.size(); i++) {
                String cartInfoStr = cartInfoList.get(i).getCartInfo();
                JSONObject jsonObject = JSONObject.parseObject(cartInfoStr);
                JSONObject coupon = jsonObject.getJSONObject("coupon");
                if(coupon != null){
                    Integer id = coupon.getInteger("id");
                    this.useCoupon(id, orderNum);
                }
            }
        }
    }
}